/******************************************************************************************
文件名：tcp_comm.h
作者：狼狼    版本：V2.0    创建日期：2021.8.3
文件描述：
    头文件。
历史修改记录：
1. 2021-8-3:V2.0 狼狼
创建。
2. 2022-5-11:V2.0 狼狼
代码公开。
******************************************************************************************/
#ifndef TCP_COMM__
#define TCP_COMM__
//+------------------------------------------------------------------------------------------+
//|                                           头文件
//+------------------------------------------------------------------------------------------+
/*|*/#include <stdbool.h>
/*|*/#include <pthread.h>
/*|*/#include "ringbuffer.h"
//+------------------------------------------------------------------------------------------+
//|                                         参数宏定义
//+------------------------------------------------------------------------------------------+
//|    ----------------------------------------
//|    TCP接收缓存(Cache)长度
//|    NOTE:接收缓存是用于将从recv系统调用获取
//|         的数据转移到应用层接收缓冲区的一小
//|         片临时内存。
//|    ----------------------------------------
/*|*/#define RECV_CACHE_LEN 100
//|    ----------------------------------------
//|    应用层收发缓冲区默认大小
//|    ----------------------------------------
/*|*/#define TX_BUF_SIZE 1024*1024*2
/*|*/#define RX_BUF_SIZE 512
//|
/*|*/#define TCPCOMM_SUCCESS               0x00000000
//|    ----------------------------------------
//|    错误码：非法的参数
//|    ----------------------------------------
/*|*/#define TCPCOMM_ERROR_ILLEGAL_PARAM   0x90021001
//|    ----------------------------------------
//|    错误码：套接字错误
//|    ----------------------------------------
/*|*/#define TCPCOMM_ERROR_SOCKET          0x90021002
//|    ----------------------------------------
//|    错误码：申请内存错误
//|    ----------------------------------------
/*|*/#define TCPCOMM_ERROR_MALLOC          0x90021003
//|    ----------------------------------------
//|    错误码：初始化应用层缓冲区错误
//|    ----------------------------------------
/*|*/#define TCPCOMM_ERROR_BUFFER          0x90021004
//|    ----------------------------------------
//|    错误码：当前套接字状态不支持此操作
//|    ----------------------------------------
/*|*/#define TCPCOMM_ERROR_UNEXPECT_STATE  0x90022001
//|    ----------------------------------------
//|    错误码：待存入的数据长度超出合法范围
//|    ----------------------------------------
/*|*/#define TCPCOMM_ERROR_UNEXPECT_DATA_LENGTH 0x90022002
//|    ----------------------------------------
//|    错误码：待更新的数据长度超出合法范围
//|    ----------------------------------------
/*|*/#define TCPCOMM_ERROR_UNEXPECT_UPDATE_LENGTH 0x90022003
//|
//|    ----------------------------------------
//|    退出原因状态码：
//|    0.未退出(TCPCOMM_SUCCESS)     0x00000000
//|    1.发送缓冲区异常              0x9002E001
//|    2.接收缓冲区异常              0x9002E002
//|    3.连接断开或会话被主动关闭    0x9002E003
//|    4.send系统调用失败            0x9002E004
//|    5.recv系统调用失败            0x9002E005
//|    6.select系统调用失败          0x9002E006
//|    7.rx_cache申请失败            0x9002E007
//|    ----------------------------------------
/*|*/#define TCPCOMM_EXIT_STAT_TX_BUF_ERROR        0x9002E001
/*|*/#define TCPCOMM_EXIT_STAT_RX_BUF_ERROR        0x9002E002
/*|*/#define TCPCOMM_EXIT_STAT_DISCONNECT_OR_CLOSE 0x9002E003
/*|*/#define TCPCOMM_EXIT_STAT_SEND_ERROR          0x9002E004
/*|*/#define TCPCOMM_EXIT_STAT_RECV_ERROR          0x9002E005
/*|*/#define TCPCOMM_EXIT_STAT_SELECT_ERROR        0x9002E006
/*|*/#define TCPCOMM_EXIT_STAT_CACHE_FAIL          0x9002E007
//+------------------------------------------------------------------------------------------+
//|                                          数据类型
//+------------------------------------------------------------------------------------------+
//|    ----------------------------------------
//|    用于描述套接字状态的枚举类型
//|    NOTE:仅内部使用
//|    ----------------------------------------
/*|*/typedef enum tcp_communicate_state
/*|*/{
/*|*/    TCPCOMM_STAT_INIT = 0,
/*|*/    TCPCOMM_STAT_OK,
/*|*/    TCPCOMM_STAT_EXIT, // 会话的处理线程因故退出，等待回收会话资源
/*|*/}ENUM_TCP_COMM_STATE;
//|
//|    ----------------------------------------
//|    用于存储一个TCP服务端对象必要信息的结构
//|    ----------------------------------------
/*|*/typedef struct tcp_comm
/*|*/{
//|      ----------------------------------------
//|      TCP通信套接字
//|      ----------------------------------------
/*|*/    int comm_sock;
//|      ----------------------------------------
//|      该TCP通信会话持有的ID
//|      NOTE:会话ID在创建处理线程时分配，若处理
//|           线程创建失败等，则不会为该连接分配
//|           ID，因为ID是设计用于会话轮询和信息
//|           打印。
//|      ----------------------------------------
/*|*/    uint32_t session_id;
//|      ----------------------------------------
//|      描述该连接的IP四元组信息
//|      ----------------------------------------
/*|*/    char local_ip_address[16];
/*|*/    char remote_ip_address[16];
/*|*/    int local_ip_port;
/*|*/    int remote_ip_port;
//|      ----------------------------------------
//|      专属于此套接字的应用层收发缓冲区
//|      ----------------------------------------
/*|*/    ST_RING_BUFFER tx_buf;
/*|*/    ST_RING_BUFFER rx_buf;
//|      ----------------------------------------
//|      TCP通信处理实例运行许可
//|      NOTE:此标志位为处理线程循环判断标志。
//|      ----------------------------------------
/*|*/    bool flag_run;
//|      ----------------------------------------
//|      套接字对象结构状态信息
//|      ----------------------------------------
/*|*/    ENUM_TCP_COMM_STATE state;
//|      ----------------------------------------
//|      套接字会话处理（子）线程退出状态码
//|      ----------------------------------------
/*|*/    int exit_state;
//|      ----------------------------------------
//|      TCP通信处理线程句柄
//|      ----------------------------------------
/*|*/    pthread_t tid;
//|      ----------------------------------------
//|      TCP通信处理子线程句柄
//|      ----------------------------------------
/*|*/    pthread_t tid2;
//|      ----------------------------------------
//|      回调函数集
//|      NOTE:以下函数指针在初始化套接字对象时被
//|           赋值。
//|      ATTENTION:使用套接字结构对象成员函数指针
//|                前必须先对其进行初始化！
//|      ----------------------------------------
/*|*/    int (*stop)             (struct tcp_comm * const ptcpcomm_obj);
/*|*/    int (*send_data)        (struct tcp_comm * const ptcpcomm_obj, const uint8_t *pdata, uint32_t len);
/*|*/    int (*get_data_len)     (struct tcp_comm * const ptcpcomm_obj, uint32_t *plen);
/*|*/    int (*get_data_point)   (struct tcp_comm * const ptcpcomm_obj, uint8_t **ppdata);
/*|*/    int (*update_data_point)(struct tcp_comm * const ptcpcomm_obj, uint32_t len);
/*|*/    int (*wait_for_data)    (struct tcp_comm * const ptcpcomm_obj);
/*|*/    int (*clear_tx_buf)     (struct tcp_comm * const ptcpcomm_obj);
/*|*/    int (*clear_rx_buf)     (struct tcp_comm * const ptcpcomm_obj);
/*|*/}ST_TCP_COMM;
//+------------------------------------------------------------------------------------------+

#ifdef __cplusplus
extern "C" {
#endif
//+------------------------------------------------------------------------------------------+
//|                                       函数/变量声明
//+------------------------------------------------------------------------------------------+
/*|*/int tcp_comm_create(ST_TCP_COMM **pptcpcomm_obj, int comm_sock);
/*|*/int tcp_comm_destroy(ST_TCP_COMM **pptcpcomm_obj);
//+------------------------------------------------------------------------------------------+
#ifdef __cplusplus
}
#endif /* End of __cplusplus*/

#endif /* End of #define TCP_COMM__ */
